package net.siufung.security.api.service.defaults;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.AllArgsConstructor;
import net.siufung.boot.jwt.service.IJwtService;
import net.siufung.core.exception.BizServiceException;
import net.siufung.core.model.consts.Constants;
import net.siufung.core.result.ResultFail;
import net.siufung.security.api.properties.SecurityProperties;
import net.siufung.security.api.service.IAccessTokenService;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.Date;

/**
 * @author 陈建峰
 * @since 2022/3/3 9:46 下午
 */
@Component("accessTokenService")
@AllArgsConstructor
@EnableConfigurationProperties({SecurityProperties.class})
public class DefaultAccessTokenServiceImpl implements IAccessTokenService {

    private final IJwtService jwtService;
    private final SecurityProperties securityProperties;

    @Override
    public JSONObject getValidTokenObj(String token) {
        if(StrUtil.isBlank(token)){
            throw new RuntimeException("令牌不能为空！");
        }
        if(!token.startsWith(Constants.BEARER)){
            throw new RuntimeException("令牌请求头不合规范！");
        }
        token = StrUtil.subSuf(token, Constants.BEARER.length());
        if(jwtService.isInvalid(token)){
            throw new BizServiceException("令牌认证失败！");
        }
        String currentUserStr = this.getValidToken(token);
        return JSONObject.parseObject(
                StrUtil.blankToDefault(currentUserStr, StrUtil.EMPTY_JSON));
    }

    @Override
    public String getValidToken(String token) {
        if(StrUtil.isNotBlank(token) && jwtService.isInvalid(token)){
            throw new BizServiceException(ResultFail.AUTH_INVALID_TOKEN.getMessage());
        }
        return JSON.toJSONString(
                jwtService.parseJwt(token),
                SerializerFeature.BrowserCompatible);
    }

    @Override
    public boolean ignoreUrlForToken(String url) {
        return securityProperties.getIgnore().getUrls().stream()
                .anyMatch(pattern -> new AntPathMatcher().match(StrUtil.trim(StrUtil.toString(pattern)),url));
    }

    @Override
    public void setExpirationDate(String token, Date expireDate) {
        jwtService.setExpireDate(token, expireDate);
    }

}
